﻿using Funq;
using ServiceStack;
using AcexeService.ServiceInterface;
using System.Web.Mvc;
using ServiceStack.Mvc;
using ServiceStack.Data;
using ServiceStack.Auth;
using ServiceStack.OrmLite;
using System.Collections.Generic;
using System.DirectoryServices.AccountManagement;
using ServiceStack.Logging;
using ServiceStack.Logging.Log4Net;
 
 

namespace AcexeService
{
    public class AppHost : AppHostBase
    {

        public AppHost() : base("AcexeService", typeof(MyServices).Assembly) { }

        public override void Configure(Container container)
        {
            LogManager.LogFactory = new Log4NetFactory(configureLog4Net: true); 
            
            SetConfig(new HostConfig
            {
                DebugMode = true,
                HandlerFactoryPath = "api",
                AddRedirectParamsToQueryString = true,
            });

            //Set MVC to use the same Funq IOC as ServiceStack
            ControllerBuilder.Current.SetControllerFactory(new FunqControllerFactory(container));

            Plugins.Add(new PostmanFeature());
            Plugins.Add(new CorsFeature());
            Plugins.Add(new SessionFeature());

            Plugins.Add(new AuthFeature(() => new CustomUserSession(),
                new IAuthProvider[]
                {
                    new AspNetWindowsAuthProvider(this) {  // Integrated Windows Auth
                        LoadUserAuthFilter = LoadUserAuthInfo,
                        AllowAllWindowsAuthUsers = true
                    },
                    //new CredentialsAuthProvider(),              //HTML Form post of UserName/Password credentials
                    new CustomCredentialsAuthProvider(),
                    new BasicAuthProvider(),                    //Sign-in with HTTP Basic Auth
                    new DigestAuthProvider(AppSettings),        //Sign-in with HTTP Digest Auth
                })
            {
                HtmlRedirect = "/",
                IncludeRegistrationService = false,
            });

            container.Register<IDbConnectionFactory>(c =>
                new OrmLiteConnectionFactory(AppSettings.GetString("AppDb"), SqlServerDialect.Provider));

            container.Register<IAuthRepository>(c =>
                new OrmLiteAuthRepository(c.Resolve<IDbConnectionFactory>())
                {
                    UseDistinctRoleTables = false
                });

            var authRepo = (OrmLiteAuthRepository)container.Resolve<IAuthRepository>();

            // OrmLiteAuthRepository Db tables have not been initialized. Try calling 'InitSchema()' in your AppHost Configure method.
            authRepo.InitSchema();

        }

        public void LoadUserAuthInfo(AuthUserSession userSession, IAuthTokens tokens, Dictionary<string, string> authInfo)
        {
            if (userSession == null)
                return;

            using (var pc = new PrincipalContext(ContextType.Domain))
            {
                var user = UserPrincipal.FindByIdentity(pc, userSession.UserAuthName);

                tokens.DisplayName = user.DisplayName;
                tokens.Email = user.EmailAddress;
                tokens.FirstName = user.GivenName;
                tokens.LastName = user.Surname;
                tokens.FullName = string.IsNullOrWhiteSpace(user.MiddleName)
                    ? "{0} {1}".Fmt(user.GivenName, user.Surname)
                    : "{0} {1} {2}".Fmt(user.GivenName, user.MiddleName, user.Surname);
                tokens.PhoneNumber = user.VoiceTelephoneNumber;
            }
        }
    }
}